<template>
  <div>
    <q-pull-to-refresh @refresh="onRefresh" ref="pullToRefreshRef">
      <q-infinite-scroll 
        @load="onLoad" 
        :offset="250" 
        class="infinite-list-container"
        ref="infiniteScrollRef"
        :disable="isDisabled"
      >
        <!-- 使用插槽来放置具体的列表内容 -->
        <slot :data="listData" :loading="loading" :refreshing="refreshing"></slot>

        <template v-slot:loading>
          <div class="row justify-center q-my-md">
            <q-spinner-dots color="primary" size="40px" />
          </div>
        </template>
      </q-infinite-scroll>
    </q-pull-to-refresh>

    <!-- 空状态显示 -->
    <div v-if="listData.length === 0 && !loading && !refreshing" class="empty-state">
      <slot name="empty">
        <q-icon name="inbox" size="64px" color="grey-5" />
        <div class="text-grey-6 q-mt-md">暂无数据</div>
      </slot>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onActivated, onDeactivated, defineProps, defineEmits } from 'vue'

// 定义 props
const props = defineProps({
  // 数据加载函数，需要返回 Promise
  loadFunction: {
    type: Function,
    required: true
  },
  // 额外参数，会传递给 loadFunction
  loadParams: {
    type: [Object, Array],
    default: () => ({})
  },
  // 数据字段名，用于从 API 响应中提取列表数据
  dataField: {
    type: String,
    default: 'data'
  },
  // 分页信息字段名
  paginationField: {
    type: String,
    default: 'pagination'
  },
  // 初始页码
  initialPage: {
    type: Number,
    default: 1
  },
  // 滚动加载触发距离
  scrollOffset: {
    type: Number,
    default: 250
  }
})

// 定义事件
const emit = defineEmits(['refresh', 'load', 'error'])

// 响应式数据
const listData = ref([])
const loading = ref(false)
const refreshing = ref(false)
const currentPage = ref(props.initialPage)
const hasMore = ref(true)
const isDisabled = ref(false) // 控制无限滚动是否禁用

// 组件引用
const infiniteScrollRef = ref(null)
const pullToRefreshRef = ref(null)

// 加载数据
const loadData = async (page) => {
  try {
    let result
    // 支持多种参数传递方式
    if (Array.isArray(props.loadParams)) {
      // 如果是数组，使用展开运算符传递参数
      result = await props.loadFunction(page, ...props.loadParams)
    } else if (
      typeof props.loadParams === 'object' &&
      props.loadParams !== null &&
      Object.keys(props.loadParams).length > 0
    ) {
      // 如果是对象，将页码和其他参数合并
      result = await props.loadFunction({ page, ...props.loadParams })
    } else {
      // 默认只传递页码
      result = await props.loadFunction(page)
    }

    return result
  } catch (error) {
    emit('error', error)
    throw error
  }
}

// 下拉刷新
const onRefresh = async (done) => {
  if (isDisabled.value) {
    done()
    return
  }
  
  refreshing.value = true
  try {
    // 重置分页参数
    currentPage.value = props.initialPage
    hasMore.value = true

    // 加载第一页数据
    const result = await loadData(props.initialPage)

    // 替换整个列表数据（而不是追加）
    listData.value = result[props.dataField] || []

    // 判断是否还有更多数据
    const pagination = result[props.paginationField]
    if (pagination) {
      hasMore.value = pagination.last_page > currentPage.value
      currentPage.value = props.initialPage + 1 // 下次加载下一页
    } else {
      hasMore.value = false
    }

    emit('refresh', result)
    done()
  } catch (error) {
    console.error('刷新数据失败:', error)
    done()
  } finally {
    refreshing.value = false
  }
}

// 无限滚动加载
const onLoad = async (index, done) => {
  // 如果组件被禁用或正在刷新，不执行滚动加载
  if (isDisabled.value || refreshing.value) {
    done()
    return
  }

  if (!hasMore.value) {
    done()
    return
  }

  loading.value = true
  try {
    const result = await loadData(currentPage.value)
    const newData = result[props.dataField] || []

    // 追加新数据
    listData.value.push(...newData)

    // 判断是否还有更多数据
    const pagination = result[props.paginationField]
    if (pagination) {
      hasMore.value = pagination.last_page > currentPage.value
    } else {
      hasMore.value = false
    }

    currentPage.value++
    emit('load', result)
    done()
  } catch (error) {
    console.error('加载数据失败:', error)
    hasMore.value = false
    done()
  } finally {
    loading.value = false
  }
}

// keep-alive 激活时
onActivated(() => {
  isDisabled.value = false
  
  // 重新启用无限滚动
  if (infiniteScrollRef.value) {
    infiniteScrollRef.value.resume()
  }
})

// keep-alive 停用时
onDeactivated(() => {
  isDisabled.value = true
  
  // 停止无限滚动
  if (infiniteScrollRef.value) {
    infiniteScrollRef.value.stop()
  }
  
  // 停止任何正在进行的请求
  loading.value = false
  refreshing.value = false
})

// 暴露方法给父组件
defineExpose({
  refresh: () => onRefresh(() => { }),
  reset: () => {
    listData.value = []
    currentPage.value = props.initialPage
    hasMore.value = true
    loading.value = false
    refreshing.value = false
  },
  // 新增方法
  enable: () => {
    isDisabled.value = false
  },
  disable: () => {
    isDisabled.value = true
  }
})

// 初始加载
onMounted(() => {
  // 初始数据会通过 q-infinite-scroll 自动加载
})
</script>

<style scoped>
.infinite-list-container {
  flex: 1;
  overflow: auto;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 50vh;
  text-align: center;
}
</style>